﻿using System.Threading;
using JetBlack.Diagnostics;

namespace JetBlack.Services
{
    /// <summary>
    /// A generic class which creates a manageable server in a thread.
    /// </summary>
    /// <typeparam name="ManageableServer">A manageable server.</typeparam>
    public class ManagedServer<ManageableServer> where ManageableServer : IManageableServer
    {
        private ManageableServer server = default(ManageableServer);
        private Thread serverThread = null;

        /// <summary>
        /// The default constructor.
        /// </summary>
        public ManagedServer()
        {
        }

        /// <summary>
        /// Construct a managed server initialised with a manageable server.
        /// </summary>
        /// <param name="server"></param>
        public ManagedServer(ManageableServer server)
        {
            this.server = server;
        }

        /// <summary>
        /// Start the contained server.
        /// </summary>
        /// <param name="args">The startup parameters.</param>
        public void Start(string[] args)
        {
            if (serverThread != null)
            {
                server.TraceSource.Warning("The server is already running");
            }
            else
            {
                serverThread = new Thread(x => server.Start((string[])x))
                {
                    Name = "ManagerThread",
                    IsBackground = true
                };

                serverThread.Start(args);
            }
        }

        /// <summary>
        ///  Stop the server.
        /// </summary>
        public void Stop()
        {
            if (serverThread == null)
            {
                server.TraceSource.Warning("The server is not running");
            }
            else
            {
                server.Stop();
                serverThread.Join();
                serverThread = null;
            }
        }

        /// <summary>
        /// Pause the server.
        /// </summary>
        public void Pause()
        {
            if (serverThread != null)
                server.Pause();
        }

        /// <summary>
        /// Resume the server.
        /// </summary>
        public void Resume()
        {
            if (serverThread != null)
                server.Resume();
        }

        /// <summary>
        /// The contained server.
        /// </summary>
        public ManageableServer Server
        {
            get { return server; }
            set { server = value; }
        }
    }
}
